/*
 * Copyright (C), 2013, 上海汽车集团股份有限公司
 * FileName: DataSourceWrapper.java
 * Author:   12010065
 * Date:     2013年10月9日 下午2:03:55
 * Description: //模块目的、功能描述
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.ibm.framework.rws.wrapper;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

import javax.sql.DataSource;

import com.ibm.framework.rws.schema.config.DsConfig;

/**
 * 数据源包装器
 * 
 * @author v_
 * 
 */
public class DataSourceWrapper implements DataSource {

    /**
     * 当前数据源
     */
    private DataSource currentDataSource;

    /**
     * 数据源配置对象
     */
    private DsConfig dsConfig;

    /**
     * 构造方法
     * 
     * @param dsConfig 数据源配置
     */
    public DataSourceWrapper(DsConfig dsConfig) {
        super();
        this.dsConfig = dsConfig;
        this.currentDataSource = dsConfig.getRefDataSource();
    }

    /**
     * <p>
     * Retrieves the log writer for this <code>DataSource</code> object.
     * 
     * <p>
     * The log writer is a character output stream to which all logging and tracing messages for this data source will
     * be printed. This includes messages printed by the methods of this object, messages printed by methods of other
     * objects manufactured by this object, and so on. Messages printed to a data source specific log writer are not
     * printed to the log writer associated with the <code>java.sql.DriverManager</code> class. When a
     * <code>DataSource</code> object is created, the log writer is initially null; in other words, the default is for
     * logging to be disabled.
     * 
     * @return the log writer for this data source or null if logging is disabled
     * @exception SQLException if a database access error occurs
     * @see #setLogWriter
     * @since 1.4
     */
    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return currentDataSource.getLogWriter();
    }

    /**
     * <p>
     * Sets the log writer for this <code>DataSource</code> object to the given <code>java.io.PrintWriter</code> object.
     * 
     * <p>
     * The log writer is a character output stream to which all logging and tracing messages for this data source will
     * be printed. This includes messages printed by the methods of this object, messages printed by methods of other
     * objects manufactured by this object, and so on. Messages printed to a data source- specific log writer are not
     * printed to the log writer associated with the <code>java.sql.DriverManager</code> class. When a
     * <code>DataSource</code> object is created the log writer is initially null; in other words, the default is for
     * logging to be disabled.
     * 
     * @param out the new log writer; to disable logging, set to null
     * @exception SQLException if a database access error occurs
     * @see #getLogWriter
     * @since 1.4
     */
    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
        currentDataSource.setLogWriter(out);
    }

    /**
     * <p>
     * Sets the maximum time in seconds that this data source will wait while attempting to connect to a database. A
     * value of zero specifies that the timeout is the default system timeout if there is one; otherwise, it specifies
     * that there is no timeout. When a <code>DataSource</code> object is created, the login timeout is initially zero.
     * 
     * @param seconds the data source login time limit
     * @exception SQLException if a database access error occurs.
     * @see #getLoginTimeout
     * @since 1.4
     */
    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
        currentDataSource.setLoginTimeout(seconds);
    }

    /**
     * 获取数据源配置对象
     * 
     * @return 数据源配置对象
     */
    public DsConfig getDsConfig() {
        return dsConfig;
    }

    /**
     * 设置数据源配置对象
     * 
     * @param dsConfig 数据源配置
     */
    public void setDsConfig(DsConfig dsConfig) {
        this.dsConfig = dsConfig;
    }

    /**
     * Gets the maximum time in seconds that this data source can wait while attempting to connect to a database. A
     * value of zero means that the timeout is the default system timeout if there is one; otherwise, it means that
     * there is no timeout. When a <code>DataSource</code> object is created, the login timeout is initially zero.
     * 
     * @return the data source login time limit
     * @exception SQLException if a database access error occurs.
     * @see #setLoginTimeout
     * @since 1.4
     */
    @Override
    public int getLoginTimeout() throws SQLException {
        return currentDataSource.getLoginTimeout();
    }

    /**
     * Returns an object that implements the given interface to allow access to non-standard methods, or standard
     * methods not exposed by the proxy.
     * 
     * If the receiver implements the interface then the result is the receiver or a proxy for the receiver. If the
     * receiver is a wrapper and the wrapped object implements the interface then the result is the wrapped object or a
     * proxy for the wrapped object. Otherwise return the the result of calling <code>unwrap</code> recursively on the
     * wrapped object or a proxy for that result. If the receiver is not a wrapper and does not implement the interface,
     * then an <code>SQLException</code> is thrown.
     * 
     * @param iface A Class defining an interface that the result must implement.
     * @param <T> 泛型对象
     * @return an object that implements the interface. May be a proxy for the actual implementing object.
     * @exception SQLException If no object found that implements the interface
     * @since 1.6
     */
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return currentDataSource.unwrap(iface);
    }

    /**
     * Returns true if this either implements the interface argument or is directly or indirectly a wrapper for an
     * object that does. Returns false otherwise. If this implements the interface then return true, else if this is a
     * wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped object. If this
     * does not implement the interface and is not a wrapper, return false. This method should be implemented as a
     * low-cost operation compared to <code>unwrap</code> so that callers can use this method to avoid expensive
     * <code>unwrap</code> calls that may fail. If this method returns true then calling <code>unwrap</code> with the
     * same argument should succeed.
     * 
     * @param iface a Class defining an interface.
     * @return true if this implements the interface or directly or indirectly wraps an object that does.
     * @exception SQLException if an error occurs while determining whether this is a wrapper for an object with the
     *                given interface.
     * @since 1.6
     */
    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return currentDataSource.isWrapperFor(iface);
    }

    /**
     * <p>
     * Attempts to establish a connection with the data source that this <code>DataSource</code> object represents.
     * 
     * @return a connection to the data source
     * @exception SQLException if a database access error occurs
     */
    @Override
    public Connection getConnection() throws SQLException {
        return new ConnectionWrapper(currentDataSource.getConnection());
    }

    /**
     * <p>
     * Attempts to establish a connection with the data source that this <code>DataSource</code> object represents.
     * 
     * @param username the database user on whose behalf the connection is being made
     * @param password the user's password
     * @return a connection to the data source
     * @exception SQLException if a database access error occurs
     * @since 1.4
     */
    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return new ConnectionWrapper(currentDataSource.getConnection(username, password));
    }

    /**
     * 获取日志基类
     * 
     * @return 日志
     * @exception SQLFeatureNotSupportedException SQL支持异常
     */
    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException { // TODO Auto-generated method
     *           stub return null; }
     */

}
